﻿//RtsHistorySource.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.History.Rts
{
	using System;
	using System.Collections.Generic;
	using System.Globalization;

	using Ecng.Common;
	using Ecng.Interop;

	using StockSharp.BusinessEntities;

	using LumiSoft.Net.FTP.Client;

	/// <summary>
	/// Источник для скачивания исторических сделок с RTS.
	/// </summary>
	public class RtsHistorySource : BaseHistorySource
	{
		private readonly DbfSource _dbfSource;
		private readonly TxtSource _txtSource;

		/// <summary>
		/// Создать <see cref="RtsHistorySource"/>.
		/// </summary>
		/// <param name="securityStorage">Интерфейс для доступа к хранилищу информации об инструментах.</param>
		public RtsHistorySource(ISecurityStorage securityStorage)
			: base(securityStorage)
		{
			_dbfSource = new DbfSource(SecurityStorage, SecurityIdGenerator);
			_txtSource = new TxtSource(SecurityStorage, SecurityIdGenerator);

			ExchangeBoard = ExchangeBoard.Forts;
			SaveRtsStdCombinedOnly = true;

			Port = 21;
			UserName = "anonymous";
			Password = "anonymous";
		}

		/// <summary>
		/// Адрес ftp RTS сервера.
		/// </summary>
		public string Host { get; set; }

		/// <summary>
		/// Порт ftp RTS сервера.
		/// </summary>
		public int Port { get; set; }

		/// <summary>
		/// Логин к ftp.
		/// </summary>
		public string UserName { get; set; }

		/// <summary>
		/// Пароль к ftp.
		/// </summary>
		public string Password { get; set; }

		/// <summary>
		/// Информация о площадке.
		/// </summary>
		public ExchangeBoard ExchangeBoard
		{
			get { return _dbfSource.ExchangeBoard; }
			set
			{
				if (value == null)
					throw new ArgumentNullException("value");

				_dbfSource.ExchangeBoard = value;
				_txtSource.ExchangeBoard = value;

				if (value == ExchangeBoard.Forts)
				{
					Host = "ftp.rts.ru";
					DbfDirectory = "pub/FORTS/pubstat/";
					TxtDirectory = "pub/info/stats/history/F";

					MinAvaliableTime = new DateTime(2003, 1, 4);
				}
				else if (value == ExchangeBoard.Ux)
				{
					Host = "ftp.ux.ua";
					DbfDirectory = "pub/info/statforts/";
					TxtDirectory = string.Empty;
					//"pub/info/stats/history/",

					MinAvaliableTime = new DateTime(2010, 5, 27);
				}
			}
		}

		/// <summary>
		/// Минимальная дата, для которой есть исторические данные.
		/// </summary>
		public DateTime MinAvaliableTime { get; private set; }

		/// <summary>
		/// Путь к папке с историческими данными в формате DBF.
		/// </summary>
		/// <remarks>
		/// Если значение равно пустой строке, то данные в формате DBF не обрабатываются.
		/// </remarks>
		public string DbfDirectory
		{
			get { return _dbfSource.FtpDirectory; }
			set { _dbfSource.FtpDirectory = value; }
		}

		/// <summary>
		/// Путь к папке с историческими данными в формате CSV и Excel.
		/// </summary>
		/// <remarks>
		/// Если значение равно пустой строке, то данные в формате CSV и Excel не обрабатываются.
		/// </remarks>
		public string TxtDirectory
		{
			get { return _txtSource.FtpDirectory; }
			set { _txtSource.FtpDirectory = value; }
		}

		/// <summary>
		/// Путь к директории, куда будут сохранятся скаченные файлы.
		/// </summary>
		/// <remarks>
		/// Если значение равно пустой строке, то данные сохраняются в текущую директорию.
		/// </remarks>
		public override string DumpFolder
		{
			get { return _dbfSource.DumpFolder; }
			set
			{
				if (value == null)
					throw new ArgumentNullException();

				_dbfSource.DumpFolder = value;
				_txtSource.DumpFolder = value;
			}
		}

		/// <summary>
		/// Склеивать сделки для инструментов РТС Стандарт (сделки для T+N не разбиваются по папкам).
		/// </summary>
		public bool SaveRtsStdCombinedOnly
		{
			get { return _dbfSource.SaveRtsStdCombinedOnly; }
			set { _dbfSource.SaveRtsStdCombinedOnly = value; }
		}

		/// <summary>
		/// Сохранять только системные сделки. По-умолчанию включено.
		/// </summary>
		public bool IsSystemOnly
		{
			get { return _dbfSource.IsSystemOnly; }
			set
			{
				_dbfSource.IsSystemOnly = value;
				_txtSource.IsSystemOnly = value;
			}
		}

		/// <summary>
		/// Загрузить исторические сделки.
		/// </summary>
		/// <param name="date">Дата торговой сессии, для которой необходимо получить сделки.</param>
		/// <param name="trades">Контейнер для загруженных сделок.</param>
		/// <returns>Исторические сделки.</returns>
		public void LoadTrades(DateTime date, IDictionary<Security, IList<Trade>> trades)
		{
			if (trades == null)
				throw new ArgumentNullException("trades");

			if (!DumpFolder.IsEmpty())
				DumpFolder.CreateDirIfNotExists();

			using (var client = new FTP_Client())
			{
				client.Connect(Host, Port);
				client.Authenticate(UserName, Password);

				CultureInfo.InvariantCulture.DoInCulture(() =>
				{
					_dbfSource.ProcessTrades(trades, client, date);
					_txtSource.ProcessTrades(trades, client, date);
				});
			}
		}
	}
}